// 通用功能类，与业务无关的功能实现

// 防止头文件被重复包含，其他文件也有
#ifndef __M_UTIL_H__
#define __M_UTIL_H__

#include <iostream>
#include <unistd.h>
#include <sys/stat.h>

namespace snowdragon
{
    // 再使用一个命名空间，方便和其他进行区分
    namespace util 
    {
        class Date
        {
        public:
            // 获取目前时间
            static time_t nowDate()
            {
                return time(nullptr);
            }
        };

        // 文件相关操作
        class File
        {
        public:
            // 获取父级目录，即文件所在的目录路径
            static std::string getPath(const std::string &path_name)
            {
                if (path_name.empty())      // 什么都没有，默认是当前目录
                    return ".";
                int pos = path_name.find_last_of("/\\");
                if (pos == std::string::npos)       // 找不到，也就是没有父级目录
                    return ".";
                return path_name.substr(0, pos + 1);
            }
            // 检测目录是否存在
            static bool exists(const std::string &path_name)
            {
                // return access(path_name.c_str(), F_OK) == 0;
                struct stat st; // 支持跨平台
                return stat(path_name.c_str(), &st) == 0;
            }
            // 创建目录
            static void createDirectory(const std::string &path_name)
            {
                if (path_name.empty())      // 要创建的目标，连名字都没有，无法创建
                    return;
                if (exists(path_name))      // 已经存在了，不需要处理
                    return;                // 如果存在，则无需进行下方的操作
                size_t pos = 0, index = 0; // 无需使用int,用size_t即可，因为不可能小于零
                while (index < path_name.size())
                {
                    pos = path_name.find_first_of("/\\", index); // 从index位置开始查找，记得加index，否则会陷入死循环
                    // if(pos == std::string::npos)    return;
                    if (pos == std::string::npos) // 找不到，直接创建
                    {
                        mkdir(path_name.c_str(), 0755);     // 创建目录（文件也可），权限需要注意，要在对应的文件夹里创建需要有执行（x）权限，否则创建不了，会报错
                        return;
                    }
                    if (pos == index) // 相等，后续操作无意义，进入下一循环。即可能是最开始，"/"或者"\"
                    {
                        index = pos + 1;    // 修改，否则下次再进来还是一样的位置找的
                        continue;
                    }
                    std::string path = path_name.substr(0, pos);        // 获取目录名，准备创建
                    // std::cout<<path<<std::endl;
                    if (exists(path) || path == "." || path == "..")        // 这些情况都不需要创建
                    {
                        index = pos + 1;
                        continue;
                    }
                    // std::cout<<"exists("<<path<<") "<<exists(path)<<std::endl;
                    /*int n = */ mkdir(path.c_str(), 0755); // 创建时，所在目录要有x，即执行权限，否则将创建失败
                    // std::cout << "mkdir n: " << n << std::endl;
                    // std::cout<<"exists("<<path<<") "<<exists(path)<<std::endl<<std::endl;
                    index = pos + 1;        // 方便下次进循环的查找操作
                }
            }
        };
    }
}

#endif